home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / Storage / Bento / MemHdr.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-22  |  9.3 KB  |  421 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        MemHdr.cpp
  3.  
  4.     Contains:    Class definition for ODMemBentoHandlers class.
  5.  
  6.     Owned by:    Vincent Lo
  7.  
  8.     Copyright:    © 1993 - 1995 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <6>     5/26/95    VL        1251403: Multithreading naming support.
  13.          <5>     5/16/95    EL        1249948: Implemenation truncation of memory
  14.                                     container.
  15.          <4>     12/9/94    EL        #1182308 Allows non-byte swapping
  16.                                     format/extract.
  17.          <3>    11/14/94    VL        1188257: Use Bento errors in BenotDef.h.
  18.          <2>     6/20/94    CC        ODMemoryHeap* changed to ODMemoryHeapID.
  19.          <1>     5/27/94    VL        first checked in
  20.     To Do:
  21. */
  22.  
  23. #ifndef    _ODTYPES_
  24. #include "ODTypes.h"
  25. #endif
  26.  
  27. #ifndef _MEMHDR_
  28. #include "MemHdr.h"
  29. #endif
  30.  
  31. #ifndef _BENTOHDR_
  32. #include "BentoHdr.h"
  33. #endif
  34.  
  35. #ifndef _SESSHDR_
  36. #include "SessHdr.h"
  37. #endif
  38.  
  39. #ifndef _EXCEPT_
  40. #include "Except.h"
  41. #endif
  42.  
  43. #ifndef _ODMEMORY_
  44. #include "ODMemory.h"
  45. #endif
  46.  
  47. #ifndef __CM_API__
  48. #include "CMAPI.h"
  49. #endif
  50.  
  51. #ifndef _ERRORDEF_
  52. #include "ErrorDef.xh"
  53. #endif
  54.  
  55. #ifndef _BENTODEF_
  56. #include "BentoDef.h"
  57. #endif
  58.  
  59. //==============================================================================
  60. // Constants
  61. //==============================================================================
  62.  
  63. const ODType kODBentoMemoryTypeName = "MemoryCtr";
  64.  
  65. //==============================================================================
  66. // Scalar Types
  67. //==============================================================================
  68.  
  69. struct ContainerLabelFmt {            /* Layout of a container label:            */
  70.  unsigned char  magicBytes[8];        /* 8 bytes: the magic byte identifier    */
  71.  unsigned short flags;                /* 2    the label flag                    */
  72.  unsigned short bufSize;            /* 2    TOC buffer size / 1024            */
  73.  unsigned short majorVersion;        /* 2    major format version number        */
  74.  unsigned short minorVersion;        /* 2    minor format version number        */
  75.  unsigned long    tocOffset;            /* 4    offset to start of TOC            */
  76.  unsigned long    tocSize;            /* 4    total byte size of the TOC        */
  77. };
  78. typedef struct ContainerLabelFmt ContainerLabelFmt;
  79.  
  80.  
  81. #pragma segment MemHdr
  82.  
  83. //==============================================================================
  84. // ODMemBentoHandlers
  85. //==============================================================================
  86.  
  87. ODMemBentoHandlers::ODMemBentoHandlers(CMSession session, ODHandle data)
  88. {
  89.     fSession        = session;    
  90.     fData           = data;
  91.     fAllocated      = kODFalse;
  92.     fSize           = 0;
  93.     fSeekValid      = kODFalse;
  94.     fSeekPos        = 0;
  95.     fLastSeekOffset = 0;
  96.     fLastSeekMode   = 0;
  97.     fEOFReached     = kODFalse;
  98.     fZone            = kODNULL;
  99.     fCurZone        = kODNULL;
  100. }
  101.  
  102. ODMemBentoHandlers::~ODMemBentoHandlers()
  103. {
  104. }
  105.  
  106. void ODMemBentoHandlers::Initialize()
  107. {
  108.     CMSetMetaHandler(fSession, kODBentoMemoryTypeName, (CMMetaHandler)containerMetahandler);
  109.     
  110.     if (fData)
  111.     {
  112.         fZone = HandleZone((Handle) fData);
  113.         THROW_IF_ERROR(MemError());
  114.         
  115.         this->SaveZone();
  116.         
  117.         fSize = ODGetHandleSize(fData);
  118.         OSErr err = MemError();
  119.         
  120.         this->RestoreZone();
  121.         
  122.         THROW_IF_ERROR(err);
  123.     }    
  124. }
  125.  
  126. CMSession ODMemBentoHandlers::GetCMSession()
  127. {
  128.     return fSession;
  129. }
  130.  
  131. CMRefCon ODMemBentoHandlers::OpenHandler(CMOpenMode mode)
  132. {
  133. ODUnused(mode);
  134.  
  135.     if (!fData)
  136.     {
  137.         fData = ODNewHandle(0);
  138.         THROW_IF_ERROR(MemError());
  139.         
  140.         fZone = GetZone();
  141.         THROW_IF_ERROR(MemError());
  142.         
  143.         fAllocated = kODTrue;
  144.         fSize = 0;
  145.     }
  146.     return ((CMRefCon)this);
  147. }
  148.  
  149. void ODMemBentoHandlers::CloseHandler()
  150. {
  151.     if (fAllocated)
  152.     {
  153.         OSErr    err;
  154.         
  155.         this->SaveZone();
  156.         ODDisposeHandle(fData);
  157.         err = MemError();
  158.         fAllocated = kODFalse;
  159.         this->RestoreZone();
  160.         THROW_IF_ERROR(err);
  161.     }
  162. }
  163.  
  164. CMSize ODMemBentoHandlers::FlushHandler()
  165. {
  166.     return((CMSize)0);
  167. }
  168.  
  169. CMSize ODMemBentoHandlers::SeekHandler(CM_LONG posOff, CMSeekMode mode)
  170. {
  171.     int result = 0;
  172.     
  173.     /* if nothing changed since last seek there's no need for another seek    */
  174.     if ((fSeekValid) && (fLastSeekMode == mode) && (fLastSeekOffset == (long)posOff))
  175.         return (result);
  176.  
  177.     switch(mode)
  178.     {
  179.         case kCMSeekSet:
  180.             if (posOff > fSize) 
  181.             {
  182.                 fSeekPos = fSize;
  183.                 result = -1;
  184.             }
  185.             else
  186.                 fSeekPos = posOff;
  187.             break;
  188.  
  189.         case kCMSeekEnd:
  190.             if (posOff > 0) 
  191.             {
  192.                 fSeekPos = fSize;
  193.                 result = -1;
  194.             }
  195.             else
  196.             {
  197.                 fSeekPos = fSize + posOff;
  198.                 if (fSeekPos < 0)
  199.                     result = -1;
  200.             }
  201.             break;
  202.  
  203.         default:
  204.             if (fSeekPos + posOff > fSize)
  205.             {
  206.                 fSeekPos = fSize;
  207.                 result = -1;
  208.             }
  209.             else
  210.                 fSeekPos = fSeekPos + posOff;
  211.             break;
  212.     }
  213.     
  214.     fSeekValid = kODTrue;                /* indicate seek has been done            */
  215.     fLastSeekMode = mode;                /* remember the mode that we just used    */
  216.     fLastSeekOffset = (long)posOff;        /* and also the specified offset        */
  217.     
  218.     return ((CMSize)result);
  219. }
  220.  
  221. CMSize ODMemBentoHandlers::TellHandler()
  222. {    
  223.     return fSeekPos;
  224. }
  225.  
  226. CMSize ODMemBentoHandlers::ReadHandler(CMPtr buffer, CMSize elementSize, CMCount theCount)
  227. {
  228.     size_t amountRead;
  229.     
  230.     amountRead = (size_t) (elementSize * theCount);
  231.     if (fSeekPos + amountRead > fSize)
  232.     {
  233.         amountRead = (size_t) (fSize - fSeekPos);
  234.         fEOFReached = kODTrue;
  235.     }
  236.     else
  237.         fEOFReached = kODFalse;
  238.     ODBlockMove(((char *)(*((Handle) fData))) + fSeekPos, buffer, amountRead);
  239.     
  240.     fSeekPos += amountRead;
  241.     fSeekValid = 0;                    /* stream pointer has now changed    */
  242.     
  243.     return ((CMSize)amountRead);
  244. }
  245.  
  246. CMSize ODMemBentoHandlers::WriteHandler(CMPtr buffer, CMSize elementSize, CMCount theCount)
  247. {
  248.     size_t amountWritten;
  249.     OSErr  err = noErr;
  250.     
  251.     if (theCount > 0) 
  252.     {
  253.         this->SaveZone();
  254.  
  255.         amountWritten = (size_t) (elementSize * theCount);
  256.  
  257.         if (fSeekPos + amountWritten > fSize) 
  258.         {
  259.             ODSetHandleSize(fData, fSeekPos + amountWritten);
  260.             err = MemError();
  261.             if (err == noErr) {
  262.                 fSize = ODGetHandleSize(fData);
  263.                 err = MemError();
  264.             }
  265.         }
  266.         if (err == noErr) {
  267.             ODBlockMove(buffer, ((char *)(*((Handle) fData))) + fSeekPos, amountWritten);
  268.             fSeekPos += amountWritten;
  269.             fSeekValid = 0;                /* stream pointer now changed            */
  270.         }
  271.         
  272.         this->RestoreZone();
  273.         
  274.         THROW_IF_ERROR(err);
  275.     }
  276.     else
  277.         amountWritten = 0;
  278.         
  279.     fEOFReached = kODFalse;
  280.     
  281.     return ((CMSize)amountWritten);
  282. }
  283.  
  284. CMEofStatus ODMemBentoHandlers::EOFHandler()
  285. {
  286.     return ((CMEofStatus)fEOFReached);
  287. }
  288.  
  289. CMBoolean ODMemBentoHandlers::TruncHandler(CMSize containerSize)
  290. {
  291.     CMBoolean result = kODFalse;
  292.  
  293.     if (containerSize <= fSize) {
  294.         if (containerSize != fSize) {
  295.             ODSetHandleSize(fData, containerSize);
  296.             fSize = containerSize;
  297.         }
  298.         result = kODTrue;
  299.     }
  300.     fSeekValid = 0;
  301.     return result;
  302. }
  303.  
  304. CMSize ODMemBentoHandlers::ContainerSizeHandler()
  305. {
  306.     return ((CMSize)fSize);
  307. }
  308.  
  309. void ODMemBentoHandlers::ReadLabelHandler(CMMagicBytes magicByteSequence,
  310.                                      CMContainerFlags *flags, CM_USHORT *bufSize,
  311.                                      CM_USHORT *majorVersion, CM_USHORT *minorVersion,
  312.                                      CMSize *tocOffset, CMSize *tocSize)
  313. {
  314.     unsigned long        labelSize;
  315.     ContainerLabelFmt    theLabel;
  316.  
  317.     /* Seek to the end of the label at the end of the container and read it...*/
  318.     
  319.     this->SeekHandler(-(long)sizeof(ContainerLabelFmt), kCMSeekEnd);
  320.     labelSize = (unsigned long)this->ReadHandler((CMPtr)&theLabel,
  321.                                             (CMSize)sizeof(unsigned char),
  322.                                             (CMCount)sizeof(ContainerLabelFmt));
  323.     
  324.     fSeekValid = 0;    
  325.     
  326.     if (labelSize != sizeof(ContainerLabelFmt))
  327.         THROW(kODErrBentoErr);
  328.     
  329.     /* Return all the label info... */
  330.     
  331.     ODBlockMove(theLabel.magicBytes, magicByteSequence, 8);
  332.     *flags = (CMContainerFlags)theLabel.flags;
  333.     *bufSize = (CM_USHORT)theLabel.bufSize;
  334.     *majorVersion = (CM_USHORT)theLabel.majorVersion;
  335.     *minorVersion = (CM_USHORT)theLabel.minorVersion;
  336.     *tocOffset = (CMSize)theLabel.tocOffset;
  337.     *tocSize = (CMSize)theLabel.tocSize;
  338. }
  339.  
  340. void ODMemBentoHandlers::WriteLabelHandler(CMMagicBytes magicByteSequence,
  341.                                         CMContainerFlags flags, CM_USHORT bufSize,
  342.                                         CM_USHORT majorVersion, CM_USHORT minorVersion,
  343.                                         CMSize tocOffset, CMSize tocSize)
  344. {
  345.     unsigned long        labelSize;
  346.     ContainerLabelFmt    theLabel;
  347.         
  348.     /* Fill in the label buffer with the info...                                                                                    */
  349.     
  350.     theLabel.flags        = (unsigned short)flags;
  351.     theLabel.bufSize      = (unsigned short)bufSize;
  352.     theLabel.majorVersion = (unsigned short)majorVersion; 
  353.     theLabel.minorVersion = (unsigned short)minorVersion;
  354.     theLabel.tocOffset       = (unsigned long)tocOffset;
  355.     theLabel.tocSize      = (unsigned long)tocSize;
  356.     
  357.     ODBlockMove(magicByteSequence, theLabel.magicBytes, 8);
  358.  
  359.     /* Write the label to the end of the container value... */
  360.     
  361.     this->SeekHandler(0, kCMSeekEnd);
  362.     labelSize = (unsigned long)this->WriteHandler((CMPtr)&theLabel,
  363.                                             (CMSize)sizeof(unsigned char),
  364.                                             (CMCount)sizeof(ContainerLabelFmt));
  365.     fSeekValid = kODFalse;
  366.  
  367.     if (labelSize != sizeof(ContainerLabelFmt))
  368.         THROW(kODErrBentoErr);
  369. }
  370.  
  371. CMValue ODMemBentoHandlers::ReturnParentValueHandler()
  372. {
  373.     return kODNULL;
  374. }
  375.  
  376. CM_UCHAR* ODMemBentoHandlers::ReturnContainerNameHandler()
  377. {
  378.     return kODNULL;
  379. }
  380.  
  381. CMType ODMemBentoHandlers::ReturnTargetTypeHandler(CMContainer container)
  382. {
  383. ODUnused(container);
  384.  
  385.     return kODNULL;
  386. }
  387.  
  388. void ODMemBentoHandlers::ExtractDataHandler(CMDataBuffer buffer,
  389.                                                  CMSize size, CMPrivateData data)
  390. {
  391.     if ((ODSLong)size < 0)            /* this means it is endian-ness netural    */
  392.         size = -(ODSLong)size;
  393.     ODBlockMove(buffer, data, (size_t)size);
  394. }
  395.  
  396. void ODMemBentoHandlers::FormatDataHandler(CMDataBuffer buffer,
  397.                                      CMSize size, CMPrivateData data)
  398. {
  399.     if ((ODSLong)size < 0)            /* this means it is endian-ness netural    */
  400.         size = -(ODSLong)size;
  401.  
  402.     ODBlockMove(data, buffer, (size_t)size);
  403. }
  404.  
  405.  
  406. void ODMemBentoHandlers::SaveZone()
  407. {
  408.     fCurZone = GetZone();
  409.     SetZone(fZone);
  410. }
  411.  
  412. void ODMemBentoHandlers::RestoreZone()
  413. {
  414.     if (fCurZone != kODNULL) {
  415.         SetZone(fCurZone);
  416.         fCurZone = kODNULL;
  417.     }
  418.     else
  419.         THROW(kODErrInvalidZone);
  420. }
  421.